/*
 * invulgotracker
 * Copyright (C) Thomas Andersen 2011 <thomas.1.andersen@gmail.com>
 *
 * invulgotracker is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * invulgotracker is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <string.h>
#include <glade/glade.h>
#include "config.h"
#include "gettextmacro.h"
#include "taskdetaildlg.h"

#include "invulgotrackerapp.h"

extern "C" gboolean on_dialogTask_delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
    gtk_dialog_response(GTK_DIALOG(widget), GTK_RESPONSE_CANCEL);
    return TRUE;
}

extern "C" void on_TaskDetail_response(GtkDialog *dialog, gint response_id, gpointer user_data)
{
    ((TaskDetailDlg *)user_data)->Response(response_id);
}

extern "C" void on_entry_changed(GtkEditable *cell_editable, gpointer user_data)
{
    ((TaskDetailDlg *)user_data)->CalcEstimate();
}


TaskDetailDlg::TaskDetailDlg(TaskView *taskView, TaskId &id)
{
    window = NULL;
    this->taskView = taskView;
    this->id = id;
}

TaskDetailDlg::~TaskDetailDlg()
{
    if (window) {
        g_signal_handler_disconnect(window, responseHandler);
        gtk_widget_hide(window);
        GtkWidget *widget = glade_xml_get_widget (InvulgoTrackerApp::gxml, "entryTaskBestCase");
        g_signal_handler_disconnect(widget, changeHandler1);
        widget = glade_xml_get_widget (InvulgoTrackerApp::gxml, "entryTaskMostLikely");
        g_signal_handler_disconnect(widget, changeHandler2);
        widget = glade_xml_get_widget (InvulgoTrackerApp::gxml, "entryTaskWorstCase");
        g_signal_handler_disconnect(widget, changeHandler3);
    }
}

void TaskDetailDlg::CalcEstimate()
{
    GtkWidget *widget = glade_xml_get_widget (InvulgoTrackerApp::gxml, "entryTaskBestCase");
    glong bestCase = atol(gtk_entry_get_text(GTK_ENTRY(widget)));
    widget = glade_xml_get_widget (InvulgoTrackerApp::gxml, "entryTaskMostLikely");
    glong mostLikely = atol(gtk_entry_get_text(GTK_ENTRY(widget)));
    widget = glade_xml_get_widget (InvulgoTrackerApp::gxml, "entryTaskWorstCase");
    glong worstCase = atol(gtk_entry_get_text(GTK_ENTRY(widget)));

    gdouble E = ((gdouble)bestCase + (gdouble)(4*mostLikely) + (gdouble)worstCase) / 6.0;
    gdouble SD = ((gdouble)worstCase - (gdouble)bestCase) / 6.0;
    gdouble conf95 = E + (2*SD);
    widget = glade_xml_get_widget (InvulgoTrackerApp::gxml, "labelTaskConf95");
    gchar str[21];
    sprintf(str, "%ld", (glong)conf95);
    gtk_label_set_text(GTK_LABEL(widget), str);
}



void TaskDetailDlg::Show(INotify *subscriber)
{
    this->subscriber = subscriber;

    /* Get window. */
    window = glade_xml_get_widget (InvulgoTrackerApp::gxml, "dialogTask");

    /* Setup values for estimation */
    glong bestCase = taskView->GetBestCase(id);
    gchar *bestCaseStr = (gchar *)g_malloc(21);
    sprintf(bestCaseStr,"%ld", bestCase);
    GtkWidget *widget = glade_xml_get_widget (InvulgoTrackerApp::gxml, "entryTaskBestCase");
    gtk_entry_set_text(GTK_ENTRY(widget), bestCaseStr);
    g_free(bestCaseStr);
    gtk_widget_grab_focus(widget);
    changeHandler1 = g_signal_connect(GTK_EDITABLE(widget), "changed", (GCallback) on_entry_changed, this);
    glong mostLikely = taskView->GetMostLikely(id);
    gchar *mostLikelyStr = (gchar *)g_malloc(21);
    sprintf(mostLikelyStr,"%ld", mostLikely);
    widget = glade_xml_get_widget (InvulgoTrackerApp::gxml, "entryTaskMostLikely");
    gtk_entry_set_text(GTK_ENTRY(widget), mostLikelyStr);
    g_free(mostLikelyStr);
    changeHandler2 = g_signal_connect(GTK_EDITABLE(widget), "changed", (GCallback) on_entry_changed, this);
    glong worstCase = taskView->GetWorstCase(id);
    gchar *worstCaseStr = (gchar *)g_malloc(21);
    sprintf(worstCaseStr,"%ld", worstCase);
    widget = glade_xml_get_widget (InvulgoTrackerApp::gxml, "entryTaskWorstCase");
    gtk_entry_set_text(GTK_ENTRY(widget), worstCaseStr);
    g_free(worstCaseStr);
    changeHandler3 = g_signal_connect(GTK_EDITABLE(widget), "changed", (GCallback) on_entry_changed, this);

    /* Setup calculation. */
    CalcEstimate();

    /* Setup deadline. */
    glong deadline = taskView->GetDeadline(id);
    glong year, month, day;
    if (deadline) {
        year = deadline / 10000;
        deadline -= year*10000;
        month = deadline / 100;
        day = deadline - (month*100);
    } else {
        TaskTime tt;
        year = tt.GetYear();
        month = tt.GetMonth();
        day = tt.GetDay();
    }
    widget = glade_xml_get_widget (InvulgoTrackerApp::gxml, "calendarDeadline");
    GtkCalendar *calendar = GTK_CALENDAR(widget);
    gtk_calendar_select_month(calendar, month, year);
    gtk_calendar_select_day(calendar, day);

    gboolean hasDeadline = taskView->GetHasDeadline(id);
    widget = glade_xml_get_widget (InvulgoTrackerApp::gxml, "checkbuttonTaskHasDeadline");
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), hasDeadline);
    gboolean done = taskView->GetDone(id);
    widget = glade_xml_get_widget (InvulgoTrackerApp::gxml, "checkbuttonTaskDone");
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), done);


    /* Show */
    responseHandler = g_signal_connect(window, "response", (GCallback) on_TaskDetail_response, this);
    gtk_widget_show(window);

}

void TaskDetailDlg::Response(gint responseId)
{
    /* Handle result */
    if (responseId == GTK_RESPONSE_OK) {
        /* Get values. */
        GtkWidget *widget = glade_xml_get_widget (InvulgoTrackerApp::gxml, "entryTaskBestCase");
        glong bestCase = atol(gtk_entry_get_text(GTK_ENTRY(widget)));
        widget = glade_xml_get_widget (InvulgoTrackerApp::gxml, "entryTaskMostLikely");
        glong mostLikely = atol(gtk_entry_get_text(GTK_ENTRY(widget)));
        widget = glade_xml_get_widget (InvulgoTrackerApp::gxml, "entryTaskWorstCase");
        glong worstCase = atol(gtk_entry_get_text(GTK_ENTRY(widget)));
        widget = glade_xml_get_widget (InvulgoTrackerApp::gxml, "checkbuttonTaskHasDeadline");
        gboolean hasDeadline = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
        widget = glade_xml_get_widget (InvulgoTrackerApp::gxml, "checkbuttonTaskDone");
        gboolean done = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
        widget = glade_xml_get_widget (InvulgoTrackerApp::gxml, "calendarDeadline");
        GtkCalendar *calendar = GTK_CALENDAR(widget);
        guint year, month, day;
        gtk_calendar_get_date(calendar, &year, &month, &day);
        glong deadline = (year*10000)+(month*100)+day;
        if (!hasDeadline)
            deadline = 0;

        /* Save */
        taskView->SetBestCase(id, bestCase);
        taskView->SetMostLikely(id, mostLikely);
        taskView->SetWorstCase(id, worstCase);
        taskView->SetHasDeadline(id, hasDeadline);
        taskView->SetDone(id, done);
        taskView->SetDeadline(id, deadline);
        taskView->Save();
        if (subscriber)
            subscriber->Notify(SAVED);
    }
    /* Destroy combo box and hide dialog */
    delete this;
}

